home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2004 #9 / Amiga Plus CD - 2004 - No. 09.iso / amigaplus / tools / amigaos4_only / mpega_libmad / mad / resample.c < prev    next >
C/C++ Source or Header  |  2004-08-03  |  3KB  |  119 lines

  1. /*
  2.  * mad - MPEG audio decoder
  3.  * Copyright (C) 2000-2003 Robert Leslie
  4.  *
  5.  * This program is free software; you can redistribute it and/or modify
  6.  * it under the terms of the GNU General Public License as published by
  7.  * the Free Software Foundation; either version 2 of the License, or
  8.  * (at your option) any later version.
  9.  *
  10.  * This program is distributed in the hope that it will be useful,
  11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  * GNU General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU General Public License
  16.  * along with this program; if not, write to the Free Software
  17.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  18.  *
  19.  * $Id: resample.c,v 1.10 2003/05/30 06:26:18 rob Exp $
  20.  */
  21.  
  22. # ifdef HAVE_CONFIG_H
  23. #  include "config.h"
  24. # endif
  25.  
  26. # include "global.h"
  27.  
  28. # include <string.h>
  29.  
  30. # include "resample.h"
  31. # include "fixed.h"
  32.  
  33. /*
  34.  * NAME:    resample_init()
  35.  * DESCRIPTION:    initialize resampling state
  36.  */
  37. int resample_init(struct resample_state *state,
  38.           unsigned int oldrate, unsigned int newrate)
  39. {
  40.   mad_fixed_t ratio;
  41.  
  42.   if (newrate == 0)
  43.     return -1;
  44.  
  45.   ratio = mad_f_div(oldrate, newrate);
  46.   if (ratio <= 0 || ratio > MAX_RESAMPLEFACTOR * MAD_F_ONE)
  47.     return -1;
  48.  
  49.   state->ratio = ratio;
  50.  
  51.   state->step = 0;
  52.   state->last = 0;
  53.  
  54.   return 0;
  55. }
  56.  
  57. /*
  58.  * NAME:    resample_block()
  59.  * DESCRIPTION:    algorithmically change the sampling rate of a PCM sample block
  60.  */
  61. unsigned int resample_block(struct resample_state *state,
  62.                 unsigned int nsamples, mad_fixed_t const *old,
  63.                 mad_fixed_t *new)
  64. {
  65.   mad_fixed_t const *end, *begin;
  66.  
  67.   /*
  68.    * This resampling algorithm is based on a linear interpolation, which is
  69.    * not at all the best sounding but is relatively fast and efficient.
  70.    *
  71.    * A better algorithm would be one that implements a bandlimited
  72.    * interpolation.
  73.    */
  74.  
  75.   if (state->ratio == MAD_F_ONE) {
  76.     bcopy(old, new, nsamples * sizeof(mad_fixed_t));
  77.     return nsamples;
  78.   }
  79.  
  80.   end   = old + nsamples;
  81.   begin = new;
  82.  
  83.   if (state->step < 0) {
  84.     state->step = mad_f_fracpart(-state->step);
  85.  
  86.     while (state->step < MAD_F_ONE) {
  87.       *new++ = state->step ?
  88.     state->last + mad_f_mul(*old - state->last, state->step) : state->last;
  89.  
  90.       state->step += state->ratio;
  91.       if (((state->step + 0x00000080L) & 0x0fffff00L) == 0)
  92.     state->step = (state->step + 0x00000080L) & ~0x0fffffffL;
  93.     }
  94.  
  95.     state->step -= MAD_F_ONE;
  96.   }
  97.  
  98.   while (end - old > 1 + mad_f_intpart(state->step)) {
  99.     old        += mad_f_intpart(state->step);
  100.     state->step = mad_f_fracpart(state->step);
  101.  
  102.     *new++ = state->step ?
  103.       *old + mad_f_mul(old[1] - old[0], state->step) : *old;
  104.  
  105.     state->step += state->ratio;
  106.     if (((state->step + 0x00000080L) & 0x0fffff00L) == 0)
  107.       state->step = (state->step + 0x00000080L) & ~0x0fffffffL;
  108.   }
  109.  
  110.   if (end - old == 1 + mad_f_intpart(state->step)) {
  111.     state->last = end[-1];
  112.     state->step = -state->step;
  113.   }
  114.   else
  115.     state->step -= mad_f_fromint(end - old);
  116.  
  117.   return new - begin;
  118. }
  119.